﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using BDAlertorApp.Model;
using BDAlertorApp.Protocol;
using BDAlertorApp.Service;
using BDAlertorApp.Service.impl;
using BDAlertorApp.Util;

namespace BDAlertorApp
{
    public partial class MainForm : Form
    {
        private static log4net.ILog logger = log4net.LogManager.GetLogger("MainForm");
        private SerialPortConnectService portService = SerialPortConnectService.GetInstance();
        private DataPacketProcessService dataService = DataPacketProcessService.GetInstance();

        private OnConnectionStatusNotifyEventHandler onConnectionStatusNotifyEventHandler;
        private OnPacketNotifyEventHandler onPacketNotifyEventHandler;
        private OnDlEventHandler OnDlEventHandler;

        private List<BdCardModel> bdCardList = new List<BdCardModel>();

        private Color blueColor = Color.FromArgb(4, 127, 239);

        private Color bgColor = Color.FromArgb(216,231,250);

        private Color greenColor = Color.Green;

        private Color redColor = Color.Red;

        private string sendType = "0";

        private UserControl3 uc3;

        private UserControl4 uc4;

        private int connected = 0;

        public MainForm()
        {
            InitializeComponent();
            setBtnStyle(btn_searchBdCard);
            setBtnStyle(button1);
            setBtnStyle(button2);
            setBtnStyle(button3);
            setBtnStyle(button4);
            setBtnStyle(button5);
            setBtnStyle(button6);
            setBtnStyle(button7);
            setBtnStyle(button8);

            textBox_dz.ReadOnly = true;
            textBox_value1.ReadOnly = true;
            textBox_value2.ReadOnly = true;
            textBox_bb.ReadOnly = true;

            toolStrip1.BackColor = bgColor;
            panel_set.BackColor = bgColor;

            listView_bdCard.BackColor = bgColor;
        }

        private void setBtnStyle(Button btn)
        {
            btn.FlatStyle = FlatStyle.Flat;
            btn.FlatAppearance.BorderSize = 0;
            btn.BackColor = blueColor;
            btn.ForeColor = Color.GhostWhite;
            
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            uc3 = new UserControl3();
            uc4 = new UserControl4();

            //串口号
            string[] ports = System.IO.Ports.SerialPort.GetPortNames();

            cBox_PortName.Items.AddRange(ports);
            if (ports.Length > 0)
            {
                cBox_PortName.SelectedItem = ports[0];
            }

            cBox_PortBaudRate.Items.Add("1200");
            cBox_PortBaudRate.Items.Add("2400");
            cBox_PortBaudRate.Items.Add("4800");
            cBox_PortBaudRate.Items.Add("9600");
            cBox_PortBaudRate.Items.Add("19200");
            cBox_PortBaudRate.Items.Add("38400");
            cBox_PortBaudRate.SelectedIndex = 3;

            onConnectionStatusNotifyEventHandler = new OnConnectionStatusNotifyEventHandler(DeviceConnectionStatusNotify);
            OnDlEventHandler = new OnDlEventHandler(DlNotify);

            portService.OnConnectionStatusNotify += onConnectionStatusNotifyEventHandler;      
            dataService.OnPacketNotify += onPacketNotifyEventHandler;
            dataService.OnDlNotify += OnDlEventHandler;

            ChangeConnectionStatus(portService.ConnectionStatus);

            //最后一列自适应

            columnHeader1.TextAlign = HorizontalAlignment.Center;

            listView_bdCard.Columns[2].Width = listView_bdCard.ClientSize.Width - listView_bdCard.Columns[0].Width
                                                                                - listView_bdCard.Columns[1].Width;

        }

        void DeviceConnectionStatusNotify(ConnectionStatus connectionStatus)
        {
            this.Invoke(new MethodInvoker(() =>
            {
                ChangeConnectionStatus(connectionStatus);
            }));
        }

        void ChangeConnectionStatus(ConnectionStatus connectionStatus)
        {
            changeBtns();
            if (connectionStatus == ConnectionStatus.Connected)
            {
                //已连接
                addItem("server", "串口服务器已打开");
                cBox_PortName.Enabled = false;
                cBox_PortBaudRate.Enabled = false;
                connected = 1;
            }
            else
            {
                //未连接
                addItem("server", "串口服务器已关闭");
                cBox_PortName.Enabled = true;
                cBox_PortBaudRate.Enabled = true;
                connected = 0;
            }
        }


        void DlNotify(byte[] buffer)
        {
            logger.Info("PacketNotify->");

            this.Invoke(new MethodInvoker(() =>
            {
                try
                {
                    string msg = System.Text.Encoding.Default.GetString(buffer);
                    Dictionary<string, string>  d = getDy(msg);
                    if(d["key"] == "DEBUG_GETINFO")
                    {
                        textBox_dz.Text = Convert.ToInt32(d["dz"],16)+"";
                        textBox_value1.Text = Convert.ToInt32(d["value1"],16)+"uV";
                        textBox_value2.Text = Convert.ToInt32(d["value2"],16)+"uV";
                        textBox_bb.Text = d["bb"];
                    }
                    if(d["key"] == "DEEP")
                    {
                        txt_msg.Text = txt_msg.Text +
                        "数据接收时间：" + DateTime.Now.ToString() +
                        "\r\n液位深度:" + Convert.ToInt32(d["deep"], 16) + "mm" +
                        "\r\n实时电压值" + Convert.ToInt32(d["dy"], 16) + "uV" +
                        "\r\n---------------------------------------\r\n";
                    }
                    addItem("receive", System.Text.Encoding.Default.GetString(buffer));
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }


            }));
        }

        private void btnPort_Click(object sender, EventArgs e)
        {
            logger.Info("btnPort_Click");
            if (portService.ConnectionStatus == ConnectionStatus.Connected)
            {
                portService.Stop();

                changeBtns();
            }
            else
            {
                GlobalVariable.SerialPortName = cBox_PortName.Text;
                GlobalVariable.SerialPortBaudRate = Convert.ToInt32(cBox_PortBaudRate.Text);
                
                btn_Port.Text = "开启中...";

                btn_Port.Enabled = false;

                portService.Start();
            }

            
        }

        private void changeBtns()
        {
            if (portService.ConnectionStatus == ConnectionStatus.Connected)
            {
                btn_Port.Text = "关闭串口";               
            }
            else
            {
                btn_Port.Text = "开启串口";               
            }

            btn_Port.Enabled = true;
        }

        

        private void btn_searchBdCard_Click(object sender, EventArgs e)
        {
            bdCardList.Clear();
            listView_bdCard.Items.Clear();

            portService.SendCmdData(SendProtocol.EncodeINQ());

        }

        private void addItem(string type,string value)
        {
            ListViewItem item = new ListViewItem();
            item.Text = DateTime.Now.ToString();
            item.SubItems.Add(type);
            item.SubItems.Add(value);
            listView_bdCard.Items.Insert(0,item);
        }

        private void btn_delBdCard_Click(object sender, EventArgs e)
        {
            if (SectedIndex != -1)
            {
                ListViewItem item = listView_bdCard.Items[SectedIndex];
                int index = Convert.ToInt32(item.SubItems[0].Text);

                portService.SendCmdData(SendProtocol.EncodeDEL(index));
            }
            else
            {
                //延迟800毫秒关闭的信息框
                showMessageBox("请选择卡位！");
            }
        }

        private int SectedIndex = -1;

        private void showMessageBox(string message)
        {
            //MessageBox.Show(new DelayCloseForm(800), message);
            MessageBox.Show(message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);

        }

        private void listView_bdCard_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
        {
            //e.DrawBackground();
            //e.Graphics.FillRectangle(new SolidBrush(bgColor), e.Bounds);
            //e.DrawText(TextFormatFlags.VerticalCenter);


            using (StringFormat sf = new StringFormat())
            {
                sf.LineAlignment = StringAlignment.Center;

                using (Brush brush = (Brush)new SolidBrush(bgColor))
                    e.Graphics.FillRectangle(brush, e.Bounds);
                Rectangle bounds = e.Bounds;
                --bounds.Width;
                --bounds.Height;
                e.Graphics.DrawRectangle(new Pen(bgColor), bounds);
                --bounds.Width;
                --bounds.Height;
                //e.Graphics.DrawLine(SystemPens.ActiveBorder, bounds.X, bounds.Y, bounds.Right, bounds.Y);//上
                e.Graphics.DrawLine(SystemPens.Control, bounds.X, bounds.Y, bounds.X, bounds.Bottom);//左边
                e.Graphics.DrawLine(SystemPens.Control, bounds.X-10, bounds.Bottom, bounds.Right+10, bounds.Bottom);//下边
                e.Graphics.DrawLine(new Pen(bgColor), bounds.Right, bounds.Y + 1, bounds.Right, bounds.Bottom);//右边

                // Draw the standard header background.
                //e.DrawBackground();

                // Draw the header text.
                using (Font headerFont = new Font("宋体", 9, FontStyle.Bold))
                {
                    e.Graphics.DrawString(e.Header.Text, headerFont, new SolidBrush(blueColor), e.Bounds, sf);
                }
            }
            return;
        }

        private void listView_bdCard_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            e.DrawDefault = true;
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("确认退出吗？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
            if (result == DialogResult.OK)
            {
                Dispose();
                Application.Exit();
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            portService.Stop();

            dataService.OnPacketNotify -= onPacketNotifyEventHandler;
            portService.OnConnectionStatusNotify -= onConnectionStatusNotifyEventHandler;
            dataService.OnDlNotify -= OnDlEventHandler;

            Environment.Exit(0);
        }

        /// <summary>
        /// 跟随窗体尺寸变化
        /// </summary>
        private void FormMain_SizeChanged(object sender, EventArgs e)
        {
            listView_bdCard.Columns[2].Width = listView_bdCard.ClientSize.Width - listView_bdCard.Columns[0].Width                                                                                - listView_bdCard.Columns[1].Width;
        }


        private bool clear = false;

        private void listView_bdCard_ItemActivate(object sender, EventArgs e)
        {
            ListView item = (ListView)sender;
            logger.Info(e);
            logger.Info(" =" + item.SelectedItems[0].SubItems[2].Text);
            string result = item.SelectedItems[0].SubItems[2].Text;
            Dictionary<string, string> map = getDy(result);
            if (map["key"] == "DEBUG_GETINFO")
            {
                MessageBox.Show(map["msg"]);
            }
            else
            {
                MessageBox.Show(result);
            }
        }

        private Dictionary<string,string> getDy(string msg)
        {
            Dictionary<string, string> result = new Dictionary<string, string>();
            string[] split = msg.Split(new Char[] { ':' });
            if(split[0]== "DEBUG_GETINFO")
            {
                result.Add("key",split[0]);
                string msgPk = split[1];
                msgPk = msgPk.Replace("\n", "").Replace(" ", "").Replace("\t", "").Replace("\r", "");
                string[] msgs = msgPk.Split(new Char[] { ',' });
                result.Add("dz", msgs[0]);
                result.Add("value1", msgs[1]);
                result.Add("value2", msgs[2]);
                result.Add("bb", msgs[3]);
                result.Add("msg", "设备地址："+Convert.ToInt32(msgs[0],16)+ "\n零位电压："+ Convert.ToInt32(msgs[1], 16) + "uV\n满程电压：" + Convert.ToInt32(msgs[2], 16) + "uV\n  版本号：" + msgs[3]);
            }
            else if(split[0] == "DEBUG_FORMAT")
            {
                result.Add("key", split[0]);
                result.Add("msg", split[1]);
            }
            else if (split[0] == "DEBUG_SETMIN")
            {
                result.Add("key", split[0]);
                result.Add("msg", split[1]);
            }
            else if (split[0] == "DEBUG_SETMAX")
            {
                result.Add("key", split[0]);
                result.Add("msg", split[1]);
            }
            else if (split[0] == "DEBUG_CALIBZERO")
            {
                result.Add("key", split[0]);
                result.Add("msg", split[1]);
            }
            else if (split[0] == "DEBUG_CALIBFULL")
            {
                result.Add("key", split[0]);
                result.Add("msg", split[1]);
            }
            else if (split[0] == "DEBUG_LOGEN")
            {
                result.Add("key", split[0]);
                result.Add("msg", split[1]);
            }
            else if (split[0] == "DEEP")
            {
                result.Add("key", split[0]);
                string msgPk = split[1];
                msgPk = msgPk.Replace("\n", "").Replace(" ", "").Replace("\t", "").Replace("\r", "");
                string[] msgs = msgPk.Split(new Char[] { ',' });
                result.Add("msg", split[1]);
                result.Add("deep", msgs[0]);
                result.Add("dy", msgs[1]);
            }

            return result;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (connected == 1)
            {
                portService.SendCmdData(SendProtocol.EncodeDL01());
                addItem("send", System.Text.Encoding.Default.GetString(SendProtocol.EncodeDL01()));
            }
            else
            {
                showMessageBox("串口服务器未打开");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (connected == 1)
            {
                portService.SendCmdData(SendProtocol.EncodeDL02());
                addItem("send", System.Text.Encoding.Default.GetString(SendProtocol.EncodeDL02()));
            }
            else
            {
                showMessageBox("串口服务器未打开");
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (connected == 1)
            {
                if (textBox_ldy.Text.Trim() == "")
                {
                    showMessageBox("参数不能为空");
                    return;
                }
                int ldy = 0;
                try
                {
                    ldy = int.Parse(textBox_ldy.Text);
                }
                catch (Exception ep)
                {
                    showMessageBox("参数格式不对");
                    return;
                }
                portService.SendCmdData(SendProtocol.EncodeDL03(ldy));
                addItem("send", System.Text.Encoding.Default.GetString(SendProtocol.EncodeDL03(ldy)));
            }
            else
            {
                showMessageBox("串口服务器未打开");
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (connected == 1)
            {
                if (textBox_mdy.Text.Trim() == "")
                {
                    showMessageBox("参数不能为空");
                    return;
                }
                int mdy = 0;
                try
                {
                    mdy = int.Parse(textBox_mdy.Text);
                }
                catch (Exception ep)
                {
                    showMessageBox("参数格式不对");
                    return;
                }
                portService.SendCmdData(SendProtocol.EncodeDL04(mdy));
                addItem("send", System.Text.Encoding.Default.GetString(SendProtocol.EncodeDL04(mdy)));
            }
            else
            {
                showMessageBox("串口服务器未打开");
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (connected == 1)
            {
                portService.SendCmdData(SendProtocol.EncodeDL05());
                addItem("send", System.Text.Encoding.Default.GetString(SendProtocol.EncodeDL05()));
            }
            else
            {
                showMessageBox("串口服务器未打开");
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (connected == 1)
            {
                portService.SendCmdData(SendProtocol.EncodeDL06());
                addItem("send", System.Text.Encoding.Default.GetString(SendProtocol.EncodeDL06()));
            }
            else
            {
                showMessageBox("串口服务器未打开");
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (connected == 1)
            {
                portService.SendCmdData(SendProtocol.EncodeDL07());
                addItem("send", System.Text.Encoding.Default.GetString(SendProtocol.EncodeDL07()));
            }
            else
            {
                showMessageBox("串口服务器未打开");
            }
        }

        private void txt_msg_TextChanged(object sender, EventArgs e)
        {
            txt_msg.SelectionStart = txt_msg.Text.Length;
            txt_msg.ScrollToCaret();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            txt_msg.Text = "";
        }

        private void textBox_ldy_KeyPress(object sender, KeyPressEventArgs e)
        {
            if(!(Char.IsNumber(e.KeyChar))&&e.KeyChar!=(char)8&&e.KeyChar!=(char)46)
            {
                e.Handled = true;
            }
        }

        private void textBox_mdy_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8 && e.KeyChar != (char)46)
            {
                e.Handled = true;
            }
        }
    }
}
